package hierarchy

import (
	"errors"
	"fmt"
	"gitcode.com/G-YT/ANN/server/global"
	"gitcode.com/G-YT/ANN/server/model/common/request"
	healthReq "gitcode.com/G-YT/ANN/server/model/health/request"
	"gitcode.com/G-YT/ANN/server/model/hierarchy"
	hierarchyReq "gitcode.com/G-YT/ANN/server/model/hierarchy/request"
	"gorm.io/gorm"
)

type FdArticleVideoService struct {
}

// CreateFdArticleVideo 创建FdArticleVideo记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleVideoService *FdArticleVideoService) CreateFdArticleVideo(fdArticleVideo *hierarchy.FdArticleVideo) (err error) {
	err = global.GVA_DB.Create(fdArticleVideo).Error
	return err
}

// DeleteFdArticleVideo 删除FdArticleVideo记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleVideoService *FdArticleVideoService) DeleteFdArticleVideo(fdArticleVideo hierarchy.FdArticleVideo) (err error) {
	var physique healthReq.PhysiqueArticle
	var solarTerms healthReq.FdJqArticle
	var efficacy healthReq.FdEfficacyArticle
	var disease healthReq.DiseaseArticle
	// 查询是否存在关联体質
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'video'", fdArticleVideo.ID).Preload("Physique").Preload("FdArticleVideo").First(&physique).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消體質管理中【" + physique.Physique.Name + "】與【" + physique.FdArticleVideo.Title + "】的關聯關係")
	}
	// 查询是否存在关联节气
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'video'", fdArticleVideo.ID).Preload("SolarTerms").Preload("FdArticleVideo").First(&solarTerms).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消節氣管理中【" + solarTerms.SolarTerms.JqName + "】與【" + solarTerms.FdArticleVideo.Title + "】的關聯關係")
	}
	// 查询是否存在关联功效
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'video'", fdArticleVideo.ID).Preload("Efficacy").Preload("FdArticleVideo").First(&efficacy).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消功效管理中【" + efficacy.Efficacy.Name + "】與【" + efficacy.FdArticleVideo.Title + "】的關聯關係")
	}
	// 查询是否存在关联病症
	if !errors.Is(global.GVA_DB.Where("article_id = ? AND type = 'video'", fdArticleVideo.ID).Preload("Disease", func(db *gorm.DB) *gorm.DB {
		return db.Preload("DiseaseList")
	}).Preload("FdArticleVideo").First(&disease).Error, gorm.ErrRecordNotFound) {
		return errors.New("請先取消病症管理中【" + disease.Disease.DiseaseList.Name + "】下的【" + disease.Disease.Name + "】與【" + disease.FdArticleVideo.Title + "】的關聯關係")
	}
	err = global.GVA_DB.Delete(&fdArticleVideo).Error
	return err
}

// DeleteFdArticleVideoByIds 批量删除FdArticleVideo记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleVideoService *FdArticleVideoService) DeleteFdArticleVideoByIds(ids request.IdsReq) (err error) {
	var physique healthReq.PhysiqueArticle
	var solarTerms healthReq.FdJqArticle
	var efficacy healthReq.FdEfficacyArticle
	var disease healthReq.DiseaseArticle
	// 查询是否存在关联体質
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'video'", ids.Ids).Preload("Physique").Preload("FdArticleVideo").First(&physique).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消体質管理中【" + physique.Physique.Name + "】与【" + physique.FdArticleVideo.Title + "】的关联关系")
	}
	// 查询是否存在关联节气
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'video'", ids.Ids).Preload("SolarTerms").Preload("FdArticleVideo").First(&solarTerms).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消节气管理中【" + solarTerms.SolarTerms.JqName + "】与【" + solarTerms.FdArticleVideo.Title + "】的关联关系")
	}
	// 查询是否存在关联功效
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'video'", ids.Ids).Preload("Efficacy").Preload("FdArticleVideo").First(&efficacy).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消功效管理中【" + efficacy.Efficacy.Name + "】与【" + efficacy.FdArticleVideo.Title + "】的关联关系")
	}
	// 查询是否存在关联病症
	if !errors.Is(global.GVA_DB.Where("article_id in ? AND type = 'video'", ids.Ids).Preload("Disease", func(db *gorm.DB) *gorm.DB {
		return db.Preload("DiseaseList")
	}).Preload("FdArticleVideo").First(&disease).Error, gorm.ErrRecordNotFound) {
		return errors.New("请先取消病症管理中【" + disease.Disease.DiseaseList.Name + "】下的【" + disease.Disease.Name + "】与【" + disease.FdArticleVideo.Title + "】的关联关系")
	}
	err = global.GVA_DB.Delete(&[]hierarchy.FdArticleVideo{}, "id in ?", ids.Ids).Error
	return err
}

// UpdateFdArticleVideo 更新FdArticleVideo记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleVideoService *FdArticleVideoService) UpdateFdArticleVideo(fdArticleVideo hierarchy.FdArticleVideo) (err error) {
	//updateFields := map[string]interface{}{
	//	"title":          fdArticleVideo.Title,
	//	"briefly":        fdArticleVideo.Briefly,
	//	"cover":          fdArticleVideo.Cover,
	//	"video_link":     fdArticleVideo.VideoLink,
	//	"text":           fdArticleVideo.Text,
	//	"textt":          fdArticleVideo.Textt,
	//	"texttt":         fdArticleVideo.Texttt,
	//	"details":        fdArticleVideo.Details,
	//	"status":         fdArticleVideo.Status,
	//	"is_vip":         fdArticleVideo.IsVip,
	//	"level_one_id":   fdArticleVideo.LevelOneID,
	//	"level_two_id":   fdArticleVideo.LevelTwoID,
	//	"level_three_id": fdArticleVideo.LevelThreeID,
	//}
	//err = global.GVA_DB.Updates(updateFields).Error
	err = global.GVA_DB.Save(&fdArticleVideo).Error
	return err
}

// GetFdArticleVideo 根据id获取FdArticleVideo记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleVideoService *FdArticleVideoService) GetFdArticleVideo(id uint, userID uint) (fdArticleVideo hierarchy.FdArticleVideo, err error) {
	var collect hierarchy.FdArticleCollect
	var like hierarchy.FdArticleLike
	var articleVideo hierarchy.FdArticleVideo
	coErr := global.GVA_DB.Where("fd_article_id = ? and user_id = ? and fd_article_type = ?", id, userID, "video").First(&collect)
	liErr := global.GVA_DB.Where("fd_article_id = ? and user_id = ? and fd_article_type = ?", id, userID, "video").First(&like)
	db := global.GVA_DB.Where("id = ?", id).First(&articleVideo)
	err = db.Error
	if coErr.Error != nil {
		articleVideo.IsCollect = false
	} else {
		articleVideo.IsCollect = true
	}
	if liErr.Error != nil {
		articleVideo.IsPraise = false
	} else {
		articleVideo.IsPraise = true
	}
	articleVideo.PV += 1
	db.Update("pv", articleVideo.PV)
	//praise, pv := fdArticleVideoService.GetPraiseAndPv(articleVideo.PV)
	fdArticleVideo.ID = articleVideo.ID
	fdArticleVideo.CreatedAt = articleVideo.CreatedAt
	fdArticleVideo.UpdatedAt = articleVideo.UpdatedAt
	fdArticleVideo.DeletedAt = articleVideo.DeletedAt
	fdArticleVideo.LevelOneID = articleVideo.LevelOneID
	fdArticleVideo.LevelOne = articleVideo.LevelOne
	fdArticleVideo.LevelTwoID = articleVideo.LevelTwoID
	fdArticleVideo.LevelTwo = articleVideo.LevelTwo
	fdArticleVideo.LevelThreeID = articleVideo.LevelThreeID
	fdArticleVideo.FdArticleLike = articleVideo.FdArticleLike
	fdArticleVideo.FdArticleCollect = articleVideo.FdArticleCollect
	fdArticleVideo.Title = articleVideo.Title
	fdArticleVideo.Briefly = articleVideo.Briefly
	fdArticleVideo.Cover = articleVideo.Cover
	fdArticleVideo.VideoLink = articleVideo.VideoLink
	fdArticleVideo.Text = articleVideo.Text
	fdArticleVideo.Textt = articleVideo.Textt
	fdArticleVideo.Texttt = articleVideo.Texttt
	fdArticleVideo.Details = articleVideo.Details
	fdArticleVideo.Status = articleVideo.Status
	fdArticleVideo.IsVip = articleVideo.IsVip
	fdArticleVideo.PV = articleVideo.PV
	fdArticleVideo.SearchNumber = articleVideo.SearchNumber
	fdArticleVideo.PraiseNum = articleVideo.PraiseNum
	fdArticleVideo.CollectNum = articleVideo.CollectNum
	fdArticleVideo.ForwardNum = articleVideo.ForwardNum
	fdArticleVideo.CommentNum = articleVideo.CommentNum
	fdArticleVideo.IsPraise = articleVideo.IsPraise
	fdArticleVideo.IsCollect = articleVideo.IsCollect
	return
}

func (fdArticleVideoService *FdArticleVideoService) GetPraiseAndPv(num int) (praise, pv string) {
	if num < 200 {
		// 点赞量 * 0.5 拼接“w+”
		likes := int(float64(num) * 0.5)
		praise = fmt.Sprintf("%dw+", likes)
		// 浏览量直接拼接“w+”
		pv = fmt.Sprintf("%dw+", num)
	} else {
		praise = "100w+"
		pv = fmt.Sprintf("%dw+", num)
	}
	return praise, pv
}

// GetFdArticleVideoInfoList 分页获取FdArticleVideo记录
// Author [piexlmax](https://github.com/piexlmax)
func (fdArticleVideoService *FdArticleVideoService) GetFdArticleVideoInfoList(info hierarchyReq.FdArticleVideoSearch) (list []hierarchy.FdArticleVideo, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)

	// 创建db
	db := global.GVA_DB.Table("fd_article_video USE INDEX (deleted_at)")
	var fdArticleVideos []hierarchy.FdArticleVideo
	// 如果有条件搜索 下方会自动创建搜索语句
	if info.StartCreatedAt != nil && info.EndCreatedAt != nil {
		db = db.Where("created_at BETWEEN ? AND ?", info.StartCreatedAt, info.EndCreatedAt)
	}

	if info.LevelOneID != nil {
		db = db.Where("level_one_id = ?", info.LevelOneID)
	}
	if info.LevelTwoID != nil {
		db = db.Where("level_two_id = ?", info.LevelTwoID)
	}
	if info.LevelThreeID != nil {
		db = db.Where("level_three_id = ?", info.LevelThreeID)
	}
	if info.Title != "" {
		db = db.Where("title LIKE ?", "%"+info.Title+"%")
	}
	err = db.Count(&total).Error
	if err != nil {
		return
	}

	if limit != 0 {
		db = db.Limit(limit).Offset(offset)
	}

	err = db.Find(&fdArticleVideos).Error

	return fdArticleVideos, total, err
}

func (fdArticleVideoService *FdArticleVideoService) FdArticleLike(userID uint, id uint) (info hierarchy.FdArticleVideo, err error) {
	var fdArticleVideo hierarchy.FdArticleVideo
	tdb := global.GVA_DB.Where("id = ?", id).First(&fdArticleVideo)
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		uidb := tx.Where("user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "video").First(&hierarchy.FdArticleLike{})
		if errors.Is(uidb.Error, gorm.ErrRecordNotFound) {
			fdArticleVideo.PraiseNum += 1
			uidb = tx.Create(&hierarchy.FdArticleLike{
				UserID:        userID,
				FdArticleID:   id,
				FdArticleType: "video",
			})
			fdArticleVideo.IsPraise = true
		} else {
			fdArticleVideo.PraiseNum -= 1
			uidb = tx.Delete(&hierarchy.FdArticleLike{}, "user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "video")
			fdArticleVideo.IsPraise = false
		}
		return tdb.Update("praise_num", fdArticleVideo.PraiseNum).Error
	})
	//praise, pv := fdArticleVideoService.GetPraiseAndPv(fdArticleVideo.PV)
	info.ID = fdArticleVideo.ID
	info.CreatedAt = fdArticleVideo.CreatedAt
	info.UpdatedAt = fdArticleVideo.UpdatedAt
	info.DeletedAt = fdArticleVideo.DeletedAt
	info.LevelOneID = fdArticleVideo.LevelOneID
	info.LevelOne = fdArticleVideo.LevelOne
	info.LevelTwoID = fdArticleVideo.LevelTwoID
	info.LevelTwo = fdArticleVideo.LevelTwo
	info.LevelThreeID = fdArticleVideo.LevelThreeID
	info.FdArticleLike = fdArticleVideo.FdArticleLike
	info.FdArticleCollect = fdArticleVideo.FdArticleCollect
	info.Title = fdArticleVideo.Title
	info.Briefly = fdArticleVideo.Briefly
	info.Cover = fdArticleVideo.Cover
	info.VideoLink = fdArticleVideo.VideoLink
	info.Details = fdArticleVideo.Details
	info.Status = fdArticleVideo.Status
	info.IsVip = fdArticleVideo.IsVip
	info.PraiseNum = fdArticleVideo.PraiseNum
	info.CollectNum = fdArticleVideo.CollectNum
	info.ForwardNum = fdArticleVideo.ForwardNum
	info.CommentNum = fdArticleVideo.CommentNum
	info.SearchNumber = fdArticleVideo.SearchNumber
	info.PV = fdArticleVideo.PV
	info.IsPraise = fdArticleVideo.IsPraise
	info.IsCollect = fdArticleVideo.IsCollect
	return
}

func (fdArticleVideoService *FdArticleVideoService) FdArticleCollect(userID uint, id uint) (info hierarchy.FdArticleVideo, err error) {
	var fdArticleVideo hierarchy.FdArticleVideo
	tdb := global.GVA_DB.Where("id = ?", id).First(&fdArticleVideo)
	err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
		uidb := tx.Where("user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "video").First(&hierarchy.FdArticleCollect{})
		if errors.Is(uidb.Error, gorm.ErrRecordNotFound) {
			fdArticleVideo.CollectNum += 1
			uidb = tx.Create(&hierarchy.FdArticleCollect{
				UserID:        userID,
				FdArticleID:   id,
				FdArticleType: "video",
			})
			fdArticleVideo.IsCollect = true
		} else {
			fdArticleVideo.CollectNum -= 1
			uidb = tx.Delete(&hierarchy.FdArticleCollect{}, "user_id = ? and fd_article_id = ? and fd_article_type = ?", userID, id, "video")
			fdArticleVideo.IsCollect = false
		}
		return tdb.Update("collect_num", fdArticleVideo.CollectNum).Error
	})
	//praise, pv := fdArticleVideoService.GetPraiseAndPv(fdArticleVideo.PV)
	info.ID = fdArticleVideo.ID
	info.CreatedAt = fdArticleVideo.CreatedAt
	info.UpdatedAt = fdArticleVideo.UpdatedAt
	info.DeletedAt = fdArticleVideo.DeletedAt
	info.LevelOneID = fdArticleVideo.LevelOneID
	info.LevelOne = fdArticleVideo.LevelOne
	info.LevelTwoID = fdArticleVideo.LevelTwoID
	info.LevelTwo = fdArticleVideo.LevelTwo
	info.LevelThreeID = fdArticleVideo.LevelThreeID
	info.FdArticleLike = fdArticleVideo.FdArticleLike
	info.FdArticleCollect = fdArticleVideo.FdArticleCollect
	info.Title = fdArticleVideo.Title
	info.Briefly = fdArticleVideo.Briefly
	info.Cover = fdArticleVideo.Cover
	info.VideoLink = fdArticleVideo.VideoLink
	info.Details = fdArticleVideo.Details
	info.Status = fdArticleVideo.Status
	info.IsVip = fdArticleVideo.IsVip
	info.PraiseNum = fdArticleVideo.PraiseNum
	info.CollectNum = fdArticleVideo.CollectNum
	info.ForwardNum = fdArticleVideo.ForwardNum
	info.CommentNum = fdArticleVideo.CommentNum
	info.SearchNumber = fdArticleVideo.SearchNumber
	info.PV = fdArticleVideo.PV
	info.IsPraise = fdArticleVideo.IsPraise
	info.IsCollect = fdArticleVideo.IsCollect
	return
}
